/***************************************************************************/
/*                                                                         */
/* 234218 Data Structures 1, Spring 2006                                   */
/*                                                                         */
/* Homework : Wet 1					                                       */
/*                                                                         */
/***************************************************************************/

/***************************************************************************/
/*                                                                         */
/* File Name : main1.cpp                                                   */
/*                                                                         */
/* Holds the "int main()" function and the parser of the shell's           */
/* command line.                                                           */
/***************************************************************************/


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "library2.h"

/* The command's strings */
static const char commandStrInit[]			                    = "init";
static const char commandStrAddInterval[]		                = "addInterval";
static const char commandStrRemoveInterval[]		            = "removeInterval";
static const char commandStrCountIntervals[]		            = "countIntervals";
static const char commandStrShiftLeftIntervals[]	            = "shiftLeftInterval";
static const char commandDoesIntervalExist[]		            = "doesIntervalExist";
static const char commandStrQuit[]		                        = "quit";


/* we assume maximum string size is not longer than 256  */
#define  MAX_STRING_INPUT_SIZE (255)
#define StrCmp(Src1,Src2) ( 0 == strncmp(Src1,Src2,strlen(Src1)) )

typedef enum {error_free, error} errorType;

static errorType parser(char *command);

#define ValidateRead(read_parameters,required_parameters,ErrorString) if(read_parameters!=required_parameters){printf(ErrorString);return error;}


bool is_init = false;

/***************************************************************************/
/* main			                                                           */
/***************************************************************************/
int main() {
	char buffer[MAX_STRING_INPUT_SIZE];
	
	// Reading commands
	while ( NULL != fgets(buffer, MAX_STRING_INPUT_SIZE, stdin) ) {
		fflush(stdout); 
		if ( error == parser(buffer) ) break;
	};
	return 0;
}


/***************************************************************************/
/* Parser                                                                  */
/***************************************************************************/

static errorType parser(char *command) { 
	
	static void *structure = NULL; /* The general data structure */
	
	char str[MAX_STRING_INPUT_SIZE];
	
	if ( NULL == command )         return error_free;
	if ( 0    == strlen(command) ) return error_free;
	if ( StrCmp("\n", command)   ) return error_free;
	
	// On init.	
	if ( StrCmp(commandStrInit, command) ) {
		if( is_init )
		{
			printf("Init was already called.\n");
			return error_free;			
		}
		is_init = true;

		structure = init();
		if( structure == NULL ) {
			printf("Init failed.\n");
			return error;
		}
		printf("Init succeeded.\n");
		return error_free;
	}
	
	// add interval
	if ( StrCmp(commandStrAddInterval, command) ) { 
		int a,b;
		ValidateRead( sscanf(command, "%s %d %d", str, &a, &b), 3, "Add interval failed.\n" );
		int res = addInterval(structure, a, b);
		if ( res != FAILURE )
			printf("Added interval (%d,%d) .\n", a,b);
		else
			printf("Add interval failed.\n");
		return error_free;
	}
	
	// remove intervall 
	if ( StrCmp(commandStrRemoveInterval, command) ) { 
		int a,b;
		ValidateRead( sscanf(command, "%s %d %d", str, &a, &b), 3, "Remove interval failed.\n" );
		int res = removeInterval( structure, a, b );
		if ( res != FAILURE ) {
			printf("Removed interval(%d,%d) from list\n", a, b);
		}
		else
			printf("remove interval failed\n");
		return error_free;
	}
	
	// does interval exist
	if ( StrCmp(commandDoesIntervalExist, command) ) { 
		int a,b;
		ValidateRead( sscanf(command, "%s %d %d", str, &a, &b), 3, "Does exist interval failed.\n" );
		int res = doesIntervalExist( structure, a, b );
		if ( res == TRUE ) {
			printf("Interval(%d,%d) exists\n", a, b);
		}
		else
			printf("Interval(%d,%d) does not exist\n", a, b);
		return error_free;
	}
	
	// count intervals 
	if ( StrCmp(commandStrCountIntervals, command) ) { 
		int k;
		ValidateRead( sscanf(command, "%s %d", str, &k), 2, "Count intervals failed.\n" );
		int res = countIntervals(structure, k);
		if ( res != FAILURE )
			printf("Count found %d intervals\n", res);
		else
			printf("Count intervals failed.\n");
		return error_free;
	}
	
	// shift left 
	if ( StrCmp(commandStrShiftLeftIntervals, command) ) { 
		int a,k;
		ValidateRead( sscanf(command, "%s %d %d", str, &a, &k), 3, "Shift left interval failed.\n" );
		int res = shiftLeftInterval(structure, a, k );
		if (  res != FAILURE )
			printf("Shift leftinterval succeeded\n");
		else
			printf("Shift leftinterval failed\n");
		return error_free;
	}
	
	
	
	// Quit 
	if ( StrCmp(commandStrQuit, command) ) {  
		quit(structure);
		printf("Closing...\n");
		return error_free;
	}
	
	// else
	printf( "Unknown command: %s\n", command );
	
	return error;
}
